//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//    virtual void BuyTicket() // virtual + 返回值 + 函数名+ 参数 相同 = 构成多态
//    {
//        cout << "Person:  买票-全价" << endl;
//    }
//};
//
//class Student : public Person
//{
//public:
//    // 这里也都相同
//    virtual void BuyTicket()
//    {
//        cout << "Student: 买票-半价" << endl;
//    }
//};
//
//class Soldier : public Person
//{
//public:
//    // 这里也都相同
//    virtual void BuyTicket()
//    {
//        cout << "Soldier: 优先买票" << endl;
//    }
//};
//
//void Pay(Person& p)
//{
//    p.BuyTicket();
//}
//
//int main()
//{
//    Person ps;
//    Student st;
//    Soldier sd;
//
//    Pay(ps);
//    Pay(st);
//    Pay(sd);
//
//    return 0;
//}

//#include <iostream>
//using namespace std;
//class A {};
//class B : public A {};
//
//class Person
//{
//public:
//	virtual A* f()
//	{
//		cout << "virtual A* Person::f()" << endl;
//		return nullptr;
//	}
//};
//
//class Student : public Person
//{
//public:
//	B* f()
//	{
//		cout << "virtual B* Student:::f()" << endl;
//		return nullptr;
//	};
//};
//
//int main()
//{
//	Person p;
//	Student s;
//	Person* ptr = &p;
//	ptr->f();
//
//	ptr = &s;
//	ptr->f();
//
//	return 0;
//}


//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//};
//
//class Student : public Person
//{
//public:
//	~Student()
//	{
//		cout << "~Student()" << endl;
//	}
//};
//
//int main()
//{
//	Person p;
//	Student s;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//	virtual ~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//};
//
//class Student : public Person
//{
//public:
//	~Student() // 隐藏（重定义）关系 -> 重写（覆盖） 关系
//	{
//		cout << "~Student()" << endl;
//	}
//};
//
//int main()
//{
//	Person* ptr1 = new Person; // delete 调用 Person 的析构，对这个也没有影响
//	delete ptr1;
//
//	Person* ptr2 = new Student; // 但是对这样的场景会产生影响
//	delete ptr2;
//
//	return 0;
//}
//#include <iostream>
//using namespace std;
//
//class Person
//{
//public:
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//};
//
//class Student : public Person
//{
//public:
//	~Student() // 隐藏（重定义）关系 -> 重写（覆盖） 关系
//	{
//		cout << "~Student()" << endl;
//		delete[] _name;
//		cout << "delete: " << (void*)_name << endl;
//	}
//
//private:
//	char* _name = new char[10] { 'h', 'e', 'l', 'l', 'o' };
//};
//
//int main()
//{
//	// 我们期望 delete ptr 调用析构函数是一个多态调用
//	Person* ptr = new Person;
//	delete ptr;   // ptr->destructor() + operator delete(ptr)
//
//	ptr = new Student;
//	delete ptr;   // ptr->destructor() + operator delete(ptr)
//
//	return 0;
//}


//#include <iostream>
//using namespace std;
//
//class Car
//{
//public:
//	virtual void Drive() final
//	{}
//};
//
//class Benz : public Car
//{
//public:
//	virtual void Drive() // 错误	C3248	"Car::Drive": 声明为 "final" 的函数不能由 "Benz::Drive" 重写
//	{
//		cout << "Benz" << endl;
//	}
//};
//
//int main()
//{
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//
//class BMW : public Car // 如果父类是抽象类，子类必须重写才能实例化
//{
//public:
//	virtual void Drive() // 重写 注释掉就会报错：错误	C2259	“BMW” : 无法实例化抽象类
//	{
//		cout << "BMW" << endl;
//	}
//};
//
//int main()
//{
//	BMW b;
//	b.Drive();
//
//	return 0;
//}
//
//#include <iostream>
//using namespace std;
//
//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//
//class BMW : public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "BMW" << endl;
//	}
//};
//
//int main()
//{
//	Car* BMW1 = new BMW;
//	BMW1->Drive();
//
//	BMW* BMW2 = new BMW;
//	BMW2->Drive();
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Func2()" << endl;
//	}
//protected:
//	int _b = 0;
//};
//
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Func3()" << endl;
//	}
//protected:
//	int _b = 0;
//};
//
//class Derive : public Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
//protected:
//	int _d = 1;
//};
//
//int main()
//{
//	Base b;
//	cout << sizeof(b) << endl;
//
//	return 0;
//}



//#include <iostream>
//using namespace std;
//
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Base::Func1()" << endl;
//	}
//	virtual void Func2()
//	{
//		cout << "Base::Func2()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Base::Func3()" << endl;
//	}
//private:
//	int _b = 0;
//};
//
//class Derive : public Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Derive::Func1()" << endl;
//	}
//	void Func3()
//	{
//		cout << "Derive::Func3()" << endl;
//	}
//	virtual void Func4()
//	{
//		cout << "Derive::Func4()" << endl;
//	}
//private:
//	int _d = 1;
//};
//
//typedef void(*V_FUNC)(); // 把函数指针 void(*)() typedef 成 V_FUNC
//
//void Print_VFTable(V_FUNC* arr)
//{
//	printf("vfptr:%p\n", arr);
//	for (size_t i = 0; arr[i] != nullptr; ++i) // 如果编译器在最后无nullptr，就要手动传参，有几个就打印几个
//	{
//		printf("vfptr[%d]: %p\n", i, arr[i]);
//		V_FUNC Func = arr[i];
//		Func(); // 函数指针加括号->调用对应的函数
//	}
//}
//
//int main()
//{
//	Derive d;
//	Print_VFTable
//	(
//		(V_FUNC*)(*((int*)&d))// 取d对象的头四个字节 指针之间是可以互相转换的
//	);                        // 把d取地址强转成int*，解引用就取出头四个字节(int)，最后强转成V_FUNC* 传参
//	//  语法有规定：完全没有关系的类型强转也不行。
//	//	至少得有一点关系：比如指针和int
//	//	因为指针虽然是地址但是也是表示地址的编号，第几个编号的地址
//	//	指针之间可以随意转换，我想取4个字节，& d 是个 Derive* ，
//	//	接引用后就是 Derive，此时强转成 int* 解引用就是取4个字节了。
//	//	由于是 int* 要调用 Print_VFTable 函数传不过去，所以我们最外层又
//	//	强转回 V_FUNC* 了，这是一个函数指针数组的地址指针。
//	//	“内线转外线再转内线”
//
//	return 0;
//}

#include <iostream>
using namespace std;

class Base1
{
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1 = 1;
};

class Base2
{
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
	int b2 = 2;
};

class Derive : public Base1, public Base2
{
public:
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1 = 3;
};

typedef void(*V_FUNC)(); // 把函数指针 void(*)() typedef 成 V_FUNC

void Print_VFTable(V_FUNC* arr/*, size_t n*/)
{
	printf("vfptr:%p\n", arr);
	for (size_t i = 0; arr[i] != nullptr/*i < n*/; ++i) // 如果编译器在最后无nullptr，就要手动传参，有几个就打印几个
	{
		printf("vfptr[%d]: %p\n", i, arr[i]);
		V_FUNC Func = arr[i];
		Func(); // 函数指针加括号->调用对应的函数
	}
	cout << endl;
}

int main()
{
	Derive d;
	Print_VFTable((V_FUNC*)(*(int*)&d));

	// 打印Base2的虚表先强转成char* +1 是+一个字节
	Print_VFTable((V_FUNC*)(*(int*)((char*)&d + sizeof(Base1))));

	return 0;
}